#!/bin/bash -e

# Version: 0.6.0
#   1. 修复Linux 6.6 fio运行出错的问题
#   2. 支持-k参数，终止测试
# Version: 0.5.0
#   1. 支持Bianbu Linux
#   2. 在当前终端启动测试
# Version: 0.4.0
#   1. 支持stress-ng
#   2. 支持chromium
# Version: 0.3.0
#   1. 支持自动下载视频
#   2. 支持自动更新
#   3. 支持iperf3静默安装
# Version: 0.2.0

LOOP=false
KILL=false

while getopts "lkh" opt
do
    case $opt in
        l)
            LOOP=true
            ;;
        k)
            KILL=true
            ;;
        h)
            echo
            echo "Usage: $0"
            echo
            echo "Option:"
            echo "    -l Loop test"
            echo "    -k Kill all tests"
            echo
            exit 0
            ;;
        \?)
            exit 1
            ;;
    esac
done

if grep "Bianbu Linux" /etc/issue > /dev/null
then
    BL=true
    HOME=/root
    XDG_VIDEOS_DIR=/root
    export XDG_RUNTIME_DIR=/root
    export WAYLAND_DISPLAY=wayland-1
    export MESA_LOADER_DRIVER_OVERRIDE=pvr
else
    BL=false
    . $HOME/.config/user-dirs.dirs
fi

LOG_DIR=$HOME/stability-test-log
mkdir -p $LOG_DIR

if [ $LOOP = true ]
then
    # CPU测试参数
    STRESS_ENABLE=true
    # 每次测试间隔，单位：秒
    STRESS_LOOP=true
    STRESS_DURATION=3600
    STRESS_LOG=$LOG_DIR/stress-ng.log

    # DDR测试参数
    MEMTESTER_ENABLE=true
    # 线程数
    MEMTESTER_THREAD=1
    MEMTESTER_SIZE=1G
    # 循环测试：true | false，设为false时无间隔运行
    MEMTESTER_LOOP=true
    # 每次测试间隔，单位：秒
    MEMTESTER_DURATION=60
    MEMTESTER_LOG=$LOG_DIR/memtester.log

    # GPU测试参数
    GLMARK_ENABLE=true
    # 循环测试：true | false，设为false时一直运行
    GLMARK_LOOP=true
    # 每次测试间隔，单位：秒
    GLMARK_DURATION=60
    GLMARK_LOG=$LOG_DIR/glmark.log

    # VPU解码测试参数
    PLAYER_ENABLE=true
    VIDEO_FILENAME=$XDG_VIDEOS_DIR/Roast_Duck_H.265_2160p_14m.mp4
    # 循环测试：true | false，设为false时运行只一次就退出
    PLAYER_LOOP=true
    # 每次测试间隔，单位：秒
    PLAYER_DURATION=60
    PLAYER_LOG=$LOG_DIR/player.log

    # eMMC、sdcard、UDisk和SSD测试参数
    FIO_ENABLE=true
    # 循环测试：true | false，，设为false时运行只一次就退出
    FIO_LOOP=true
    # 每次测试间隔，单位：秒
    FIO_DURATION=60
    # 每次测试时间，单位：秒
    FIO_RUNTIME=3600
    FIO_EMMC_ENABLE=true
    # eMMC测试文件名，通常无需修改
    FIO_EMMC_FILENAME=$HOME/eMMC-test.bin
    # eMMC测试文件大小
    FIO_EMMC_FILESIZE=1G
    FIO_EMMC_RUNTIME=$FIO_RUNTIME
    FIO_EMMC_LOG=$HOME/fio-eMMC.log
    FIO_SDCARD_ENABLE=true
    # sdcard测试文件名
    FIO_SDCARD_FILENAME=/media/bianbu/sdcard/fio-test.bin
    # sdcard测试文件大小
    FIO_SDCARD_FILESIZE=10G
    FIO_SDCARD_RUNTIME=$FIO_RUNTIME
    FIO_SDCARD_LOG=$LOG_DIR/fio-sdcard.log
    FIO_UDISK_ENABLE=true
    # U-Disk测试文件名
    FIO_UDISK_FILENAME=/media/bianbu/udisk/fio-test.bin
    # U-Disk测试文件大小
    FIO_UDISK_FILESIZE=10G
    FIO_UDISK_RUNTIME=$FIO_RUNTIME
    FIO_UDISK_LOG=$LOG_DIR/fio-udisk.log
    FIO_SSD_ENABLE=true
    # SSD测试文件名
    FIO_SSD_FILENAME=/media/bianbu/ssd/fio-test.bin
    # SSD测试文件大小
    FIO_SSD_FILESIZE=100G
    FIO_SSD_RUNTIME=$FIO_RUNTIME
    FIO_SSD_LOG=$LOG_DIR/fio-ssd.log

    # 网络测试参数
    IPERF3_ENABLE=true
    # 循环测试：true | false，，设为false时运行只一次就退出
    IPERF3_LOOP=true
    # 每次测试间隔，单位：秒
    IPERF3_DURATION=60
    # 每次测试时间，单位：秒
    IPERF3_TIME=3600
    IPERF3_SERVER1=10.0.91.40
    IPERF3_PORT1=5201
    IPERF3_END0=false
    IPERF3_END0_IP=10.0.91.25
    IPERF3_END0_TIME=$IPERF3_TIME
    IPERF3_END0_LOG=$LOG_DIR/iperf3_end0.log
    IPERF3_SERVER2=10.0.90.237
    IPERF3_PORT2=5201
    IPERF3_END1=false
    IPERF3_END1_IP=10.0.90.55
    IPERF3_END1_TIME=$IPERF3_TIME
    IPERF3_END1_LOG=$LOG_DIR/iperf3_end1.log
    IPERF3_SERVER3=10.0.90.237
    IPERF3_PORT3=5201
    IPERF3_WLAN0=false
    IPERF3_WLAN0_IP=10.0.91.95
    IPERF3_WLAN0_TIME=$IPERF3_TIME
    IPERF3_WLAN0_LOG=$LOG_DIR/iperf3_wlan0.log

    # chromium
    CHROMIUM_ENABLE=true
    CHROMIUM_URL=https://www.bilibili.com/bangumi/play/ss33626
    CHROMIUM_LOG=$LOG_DIR/chromium.log

    # object dection
    OBJECT_ENABLE=true
    OBJECT_LOG=$LOG_DIR/object.log
else
    # CPU测试参数
    STRESS_ENABLE=true
    STRESS_LOOP=false
    STRESS_LOG=$LOG_DIR/stress-ng.log

    # DDR测试参数
    MEMTESTER_ENABLE=true
    # 线程数
    MEMTESTER_THREAD=1
    MEMTESTER_SIZE=1G
    # 循环测试：true | false，设为false时无间隔运行
    MEMTESTER_LOOP=false
    MEMTESTER_ITERATIONS=1000
    MEMTESTER_LOG=$LOG_DIR/memtester.log

    # GPU测试参数
    GLMARK_ENABLE=true
    # 循环测试：true | false，设为false时一直运行
    GLMARK_LOOP=false
    GLMARK_LOG=$LOG_DIR/glmark.log

    # VPU解码测试参数
    PLAYER_ENABLE=true
    VIDEO_FILENAME=$XDG_VIDEOS_DIR/Roast_Duck_H.265_2160p_14m.mp4
    # 循环测试：true | false，设为false时一直运行
    PLAYER_LOOP=false
    PLAYER_LOG=$LOG_DIR/player.log

    # eMMC、sdcard、UDisk和SSD测试参数
    FIO_ENABLE=true
    # 循环测试：true | false，，设为false时运行只一次就退出
    FIO_LOOP=false
    # 每次测试时间，单位：秒
    FIO_RUNTIME=86400
    FIO_EMMC_ENABLE=true
    # eMMC测试文件名，通常无需修改
    FIO_EMMC_FILENAME=$HOME/eMMC-test.bin
    # eMMC测试文件大小
    FIO_EMMC_FILESIZE=1G
    FIO_EMMC_RUNTIME=$FIO_RUNTIME
    FIO_EMMC_LOG=$LOG_DIR/fio-eMMC.log
    FIO_SDCARD_ENABLE=true
    # sdcard测试文件名
    FIO_SDCARD_FILENAME=/media/bianbu/sdcard/fio-test.bin
    # sdcard测试文件大小
    FIO_SDCARD_FILESIZE=10G
    FIO_SDCARD_RUNTIME=$FIO_RUNTIME
    FIO_SDCARD_LOG=$LOG_DIR/fio-sdcard.log
    FIO_UDISK_ENABLE=true
    # U-Disk测试文件名
    FIO_UDISK_FILENAME=/media/bianbu/udisk/fio-test.bin
    # U-Disk测试文件大小
    FIO_UDISK_FILESIZE=10G
    FIO_UDISK_RUNTIME=$FIO_RUNTIME
    FIO_UDISK_LOG=$LOG_DIR/fio-udisk.log
    FIO_SSD_ENABLE=true
    # SSD测试文件名
    FIO_SSD_FILENAME=/media/bianbu/ssd/fio-test.bin
    # SSD测试文件大小
    FIO_SSD_FILESIZE=100G
    FIO_SSD_RUNTIME=$FIO_RUNTIME
    FIO_SSD_LOG=$LOG_DIR/fio-ssd.log

    # 网络测试参数
    IPERF3_ENABLE=true
    # 循环测试：true | false，，设为false时运行只一次就退出
    IPERF3_LOOP=false
    # 每次测试间隔，单位：秒
    IPERF3_DURATION=60
    # 每次测试时间，单位：秒
    IPERF3_TIME=86400
    IPERF3_SERVER1=10.0.91.40
    IPERF3_PORT1=5201
    IPERF3_END0=false
    IPERF3_END0_IP=10.0.91.25
    IPERF3_END0_TIME=$IPERF3_TIME
    IPERF3_END0_LOG=$LOG_DIR/iperf3_end0.log
    IPERF3_SERVER2=10.0.90.237
    IPERF3_PORT2=5201
    IPERF3_END1=false
    IPERF3_END1_IP=10.0.90.55
    IPERF3_END1_TIME=$IPERF3_TIME
    IPERF3_END1_LOG=$LOG_DIR/iperf3_end1.log
    IPERF3_SERVER3=10.0.90.237
    IPERF3_PORT3=5201
    IPERF3_WLAN0=false
    IPERF3_WLAN0_IP=10.0.91.95
    IPERF3_WLAN0_TIME=$IPERF3_TIME
    IPERF3_WLAN0_LOG=$LOG_DIR/iperf3_wlan0.log

    # chromium
    CHROMIUM_ENABLE=true
    CHROMIUM_URL=https://www.bilibili.com/bangumi/play/ss33626
    CHROMIUM_LOG=$LOG_DIR/chromium.log

    # object dection
    OBJECT_ENABLE=true
    OBJECT_LOG=$LOG_DIR/object.log
fi

if [ $KILL = true ]
then
    set +e
    killall -9 stress-ng
    killall -9 memtester
    killall -9 glmark2-es2-wayland
    killall -9 mpv
    killall -9 fio
    killall -9 iperf3
    killall -9 chrome
    killall -9 PreviewThread
    exit 0
fi

run()
{
    echo "run $*"
    bash -c "$* &"
}

loop_run()
{
    echo "loop run $*"
    bash -c "while true; do $*; done &"
}

if [ $STRESS_ENABLE = true ]
then
    $BL || command -v stress-ng > /dev/null || (sudo apt-get update && sudo apt-get install -y stress-ng)
fi

if [ $MEMTESTER_ENABLE = true ]
then
    $BL || command -v memtester > /dev/null || (sudo apt-get update && sudo apt-get install -y memtester)
fi

if [ $GLMARK_ENABLE = true ]
then
    $BL || command -v glmark2-es2-wayland > /dev/null || (sudo apt-get update && sudo apt-get install -y glmark2-es2-wayland)
fi

if [ $FIO_ENABLE = true ]
then
    $BL || command -v fio > /dev/null || (sudo apt-get update && sudo apt-get install -y fio)
    if [[ `uname -r` > "6.6" ]]
    then
        echo 2 | sudo tee /proc/sys/kernel/perf_user_access
    fi
fi

if [ $IPERF3_ENABLE = true ]
then
    $BL || command -v iperf3 > /dev/null || (sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y iperf3)
fi

if [ $STRESS_ENABLE = true ]
then
    echo "Run CPU test..."
    rm -f $STRESS_LOG
    if [ $STRESS_LOOP = true ]
    then
        loop_run "stress-ng --cpu 2 --cpu-load 50 --timeout 3 >> $STRESS_LOG 2>&1"
    else
        run "stress-ng --cpu 2 --cpu-load 50 >> $STRESS_LOG 2>&1"
    fi
fi

if [ $MEMTESTER_ENABLE = true ]
then
    echo "Run DDR test..."
    for ((i=0; i<$MEMTESTER_THREAD; i++))
    do
        rm -f $MEMTESTER_LOG.$i
        if [ $MEMTESTER_LOOP = true ]
        then
            loop_run "memtester $MEMTESTER_SIZE 1 >> $MEMTESTER_LOG.$i\; echo "Sleep $MEMTESTER_DURATION..."\; sleep $MEMTESTER_DURATION 2>&1"
        else
            run "memtester $MEMTESTER_SIZE $MEMTESTER_ITERATIONS >> $MEMTESTER_LOG.$i 2>&1"
        fi
    done
fi

if [ $GLMARK_ENABLE = true ]
then
    echo "Run GPU test..."
    rm -f $GLMARK_LOG
    if [ $GLMARK_LOOP = true ]
    then
        loop_run "glmark2-es2-wayland >> $GLMARK_LOG\; echo "Sleep $GLMARK_DURATION..."\; sleep $GLMARK_DURATION 2>&1"
    else
        run "glmark2-es2-wayland --run-forever >> $GLMARK_LOG 2>&1"
    fi
fi

if [ $PLAYER_ENABLE = true ]
then
    echo "Run VPU test..."
    [ -f $VIDEO_FILENAME ] || wget -q http://nexus.bianbu.xyz/repository/video/demo/`basename $VIDEO_FILENAME` -O $VIDEO_FILENAME
    rm -f $PLAYER_LOG
    if [ -f $VIDEO_FILENAME ]
    then
        if [ $BL = true ]
        then
            run "ffplay -codec:v hevc_stcodec -ar 48000 -i $VIDEO_FILENAME -loop 10000 >> $PLAYER_LOG 2>&1"
        else
            if [ $PLAYER_LOOP = true ]
            then
                loop_run "mpv $VIDEO_FILENAME >> $PLAYER_LOG\; echo "Sleep $PLAYER_DURATION..."\; sleep $PLAYER_DURATION 2>&1"
            else
                run "mpv --loop $VIDEO_FILENAME >> $PLAYER_LOG 2>&1"
            fi
        fi
    fi
fi

if [ $FIO_EMMC_ENABLE = true ]
then
    echo "Run eMMC test..."
    rm -f $FIO_EMMC_LOG
    if [ $FIO_LOOP = true ]
    then
        loop_run "fio -filename=$FIO_EMMC_FILENAME -name=eMMC -rw=randrw -rwmixread=50 -ioengine=libaio -direct=1 -bs=16k -numjobs=2 -iodepth=20 -size=$FIO_EMMC_FILESIZE -runtime=$FIO_EMMC_RUNTIME -time_based -group_reporting\; echo "Sleep $FIO_DURATION"\; sleep $FIO_DURATION >> $FIO_EMMC_LOG 2>&1"
    else
        run "fio -filename=$FIO_EMMC_FILENAME -name=eMMC -rw=randrw -rwmixread=50 -ioengine=libaio -direct=1 -bs=16k -numjobs=2 -iodepth=20 -size=$FIO_EMMC_FILESIZE -runtime=$FIO_EMMC_RUNTIME -time_based -group_reporting >> $FIO_EMMC_LOG 2>&1"
    fi
fi

if [ $FIO_SDCARD_ENABLE = true ] && [ -d `dirname $FIO_SDCARD_FILENAME` ]
then
    echo "Run sdcard test..."
    rm -f $FIO_SDCARD_LOG
    if [ $FIO_LOOP = true ]
    then
        loop_run "fio -filename=$FIO_SDCARD_FILENAME -name=sdcard -rw=randrw -rwmixread=50 -ioengine=libaio -direct=1 -bs=16k -numjobs=2 -iodepth=20 -size=$FIO_SDCARD_FILESIZE -runtime=$FIO_SDCARD_RUNTIME -time_based -group_reporting\; echo "Sleep $FIO_DURATION"\; sleep $FIO_DURATION >> $FIO_SDCARD_LOG 2>&1"
    else
        run "fio -filename=$FIO_SDCARD_FILENAME -name=sdcard -rw=randrw -rwmixread=50 -ioengine=libaio -direct=1 -bs=16k -numjobs=2 -iodepth=20 -size=$FIO_SDCARD_FILESIZE -runtime=$FIO_SDCARD_RUNTIME -time_based -group_reporting >> $FIO_SDCARD_LOG 2>&1"
    fi
fi

if [ $FIO_UDISK_ENABLE = true ] && [ -d `dirname $FIO_UDISK_FILENAME` ]
then
    echo "Run U-Disk test..."
    rm -f $FIO_UDISK_LOG
    if [ $FIO_LOOP = true ]
    then
        loop_run "fio -filename=$FIO_UDISK_FILENAME -name=U-Disk -rw=randrw -rwmixread=50 -ioengine=libaio -direct=1 -bs=16k -numjobs=2 -iodepth=20 -size=$FIO_UDISK_FILESIZE -runtime=$FIO_UDISK_RUNTIME -time_based -group_reporting\; echo "Sleep $FIO_DURATION"\; sleep $FIO_DURATION >> $FIO_UDISK_LOG 2>&1"
    else
        run "fio -filename=$FIO_UDISK_FILENAME -name=U-Disk -rw=randrw -rwmixread=50 -ioengine=libaio -direct=1 -bs=16k -numjobs=2 -iodepth=20 -size=$FIO_UDISK_FILESIZE -runtime=$FIO_UDISK_RUNTIME -time_based -group_reporting >> $FIO_UDISK_LOG 2>&1"
    fi
fi

if [ $FIO_SSD_ENABLE = true ] && [ -d `dirname $FIO_SSD_FILENAME` ]
then
    echo "Run SSD test..."
    rm -f $FIO_SSD_LOG
    if [ $FIO_LOOP = true ]
    then
        loop_run "fio -filename=$FIO_SSD_FILENAME -name=SSD -rw=randrw -rwmixread=50 -ioengine=libaio -direct=1 -bs=16k -numjobs=2 -iodepth=20 -size=$FIO_SSD_FILESIZE -runtime=$FIO_SSD_RUNTIME -time_based -group_reporting\; echo "Sleep $FIO_DURATION"\; sleep $FIO_DURATION >> $FIO_SSD_LOG 2>&1"
    else
        run "fio -filename=$FIO_SSD_FILENAME -name=SSD -rw=randrw -rwmixread=50 -ioengine=libaio -direct=1 -bs=16k -numjobs=2 -iodepth=20 -size=$FIO_SSD_FILESIZE -runtime=$FIO_SSD_RUNTIME -time_based -group_reporting >> $FIO_SSD_LOG 2>&1"
    fi
fi

if [ $IPERF3_END0 = true ]
then
    echo "Run end0 iperf3 test..."
    rm -f $IPERF3_END0_LOG
    if [ $IPERF3_LOOP = true ]
    then
        loop_run "iperf3 -c $IPERF3_SERVER1 -p $IPERF3_PORT1 -B $IPERF3_END0_IP --bidir -t $IPERF3_END0_TIME\; echo "Sleep $IPERF3_DURATION"\; sleep $IPERF3_DURATION >> $IPERF3_END0_LOG 2>&1"
    else
        run "iperf3 -c $IPERF3_SERVER1 -p $IPERF3_PORT1 -B $IPERF3_END0_IP --bidir -t $IPERF3_END0_TIME >> $IPERF3_END0_LOG 2>&1"
    fi
fi

if [ $IPERF3_END1 = true ]
then
    echo "Run end1 iperf3 test..."
    rm -f $IPERF3_END0_LOG
    if [ $IPERF3_LOOP = true ]
    then
        loop_run "iperf3 -c $IPERF3_SERVER2 -p $IPERF3_PORT2 -B $IPERF3_END1_IP --bidir -t $IPERF3_END1_TIME\; echo "Sleep $IPERF3_DURATION"\; sleep $IPERF3_DURATION >> $IPERF3_END1_LOG 2>&1"
    else
        run "iperf3 -c $IPERF3_SERVER2 -p $IPERF3_PORT2 -B $IPERF3_END1_IP --bidir -t $IPERF3_END1_TIME >> $IPERF3_END1_LOG 2>&1"
    fi
fi

if [ $IPERF3_WLAN0 = true ]
then
    echo "Run wlan0 iperf3 test..."
    rm -f $IPERF3_WLAN0_LOG
    if [ $IPERF3_LOOP = true ]
    then
        loop_run "iperf3 -c $IPERF3_SERVER3 -p $IPERF3_PORT3 -B $IPERF3_WLAN0_IP --bidir -t $IPERF3_WLAN0_TIME\; echo "Sleep $IPERF3_DURATION"\; sleep $IPERF3_DURATION >> $IPERF3_WLAN0_LOG 2>&1"
    else
        run "iperf3 -c $IPERF3_SERVER3 -p $IPERF3_PORT3 -B $IPERF3_WLAN0_IP --bidir -t $IPERF3_WLAN0_TIME >> $IPERF3_WLAN0_LOG 2>&1"
    fi
fi

if [ $BL = false -a $CHROMIUM_ENABLE = true ]
then
    echo "Run chromium-browser test..."
    run "chromium-browser $CHROMIUM_URL >> $CHROMIUM_LOG 2>&1"
fi

if [ $BL = false -a $OBJECT_ENABLE = true ]
then
    echo "Run object detection test..."
    run "detection_stream_demo /usr/share/ai-support/models/yolov6.json 0 >> $OBJECT_LOG 2>&1"
fi

echo "All tests started, log at: $LOG_DIR"
